package com.zhiche.lisa.bms.service.fee.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.*;
import com.zhiche.lisa.bms.constant.DWaybillFeeEnum;
import com.zhiche.lisa.bms.dao.mapper.fee.FeePayableMapper;
import com.zhiche.lisa.bms.dao.mapper.price.PricePurchaseDtlMapper;
import com.zhiche.lisa.bms.dao.model.bill.Bill;
import com.zhiche.lisa.bms.dao.model.bill.BillDetail;
import com.zhiche.lisa.bms.dao.model.contract.Contract;
import com.zhiche.lisa.bms.dao.model.contract.ContractFinalpay;
import com.zhiche.lisa.bms.dao.model.contract.ContractFleetDtl;
import com.zhiche.lisa.bms.dao.model.cost.CostMid;
import com.zhiche.lisa.bms.dao.model.fee.FeePayable;
import com.zhiche.lisa.bms.dao.model.fee.FeeType;
import com.zhiche.lisa.bms.dao.model.pay.PayApplyDtlBill;
import com.zhiche.lisa.bms.dao.model.prepay.PrepayBill;
import com.zhiche.lisa.bms.dao.model.price.PriceDeductRate;
import com.zhiche.lisa.bms.dao.model.price.PricePurchase;
import com.zhiche.lisa.bms.dao.model.price.PricePurchaseDtl;
import com.zhiche.lisa.bms.dao.model.quote.Quote;
import com.zhiche.lisa.bms.dao.model.quote.QuoteDtl;
import com.zhiche.lisa.bms.dao.model.trans.TransTypeNameContrast;
import com.zhiche.lisa.bms.dao.model.waybill.WaybillState;
import com.zhiche.lisa.bms.enums.RulePriceEnum;
import com.zhiche.lisa.bms.pojo.bo.quote.FleetQuotation;
import com.zhiche.lisa.bms.pojo.bo.quote.MatchingResult;
import com.zhiche.lisa.bms.pojo.bo.quote.MatchingResultList;
import com.zhiche.lisa.bms.pojo.dto.driver.HycOrderData;
import com.zhiche.lisa.bms.pojo.dto.fee.ShipParamDTO;
import com.zhiche.lisa.bms.pojo.dto.fee.TmsReleaseDto;
import com.zhiche.lisa.bms.pojo.dto.otm.OrderReleaseStatueDto;
import com.zhiche.lisa.bms.pojo.dto.price.OrderDTO;
import com.zhiche.lisa.bms.pojo.dto.price.OrderItemDTO;
import com.zhiche.lisa.bms.pojo.dto.util.LspBasicDTO;
import com.zhiche.lisa.bms.pojo.dto.util.LspFleetDTO;
import com.zhiche.lisa.bms.pojo.dto.util.OtmServiceResult;
import com.zhiche.lisa.bms.pojo.dto.util.integration.ShipTaskDTO;
import com.zhiche.lisa.bms.pojo.dto.util.integration.ShipmentDTO;
import com.zhiche.lisa.bms.pojo.dto.util.mdm.TransportationTypeDTO;
import com.zhiche.lisa.bms.pojo.vo.common.CommonVO;
import com.zhiche.lisa.bms.pojo.vo.common.FeePermissCommonVO;
import com.zhiche.lisa.bms.pojo.vo.fee.FeePayableHeaderVO;
import com.zhiche.lisa.bms.pojo.vo.fee.FeePayablePermissVO;
import com.zhiche.lisa.bms.pojo.vo.fee.FeePayableVO;
import com.zhiche.lisa.bms.pojo.vo.price.PricePurchaseVO;
import com.zhiche.lisa.bms.pojo.vo.util.ShipOrderItemVO;
import com.zhiche.lisa.bms.service.bill.BillDetailService;
import com.zhiche.lisa.bms.service.contract.ContractFinalpayService;
import com.zhiche.lisa.bms.service.contract.ContractFleetDtlService;
import com.zhiche.lisa.bms.service.contract.ContractService;
import com.zhiche.lisa.bms.service.cost.CostMidService;
import com.zhiche.lisa.bms.service.driver.ICalcDriverCost;
import com.zhiche.lisa.bms.service.fee.FeePayableService;
import com.zhiche.lisa.bms.service.fee.FeeTypeService;
import com.zhiche.lisa.bms.service.pay.PayApplyDtlBillService;
import com.zhiche.lisa.bms.service.prepay.PrepayBillService;
import com.zhiche.lisa.bms.service.price.PriceDeductRateService;
import com.zhiche.lisa.bms.service.price.PricePurchaseService;
import com.zhiche.lisa.bms.service.psup.SdBaseComputerService;
import com.zhiche.lisa.bms.service.quote.QuoteDtlService;
import com.zhiche.lisa.bms.service.quote.QuoteService;
import com.zhiche.lisa.bms.service.sta.AmgCstService;
import com.zhiche.lisa.bms.service.sta.StaPriceService;
import com.zhiche.lisa.bms.service.trans.TransTypeNameContrastService;
import com.zhiche.lisa.bms.service.utils.*;
import com.zhiche.lisa.bms.service.waybill.WaybillStateService;
import com.zhiche.lisa.bms.utils.BmsCollectionUtils;
import com.zhiche.lisa.bms.utils.KieUtil;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.supports.RestfulResponse;
import org.joda.time.DateTime;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 应付账款 服务实现类
 * </p>
 *
 * @author zhangkun
 * @since 2018-09-03
 */
@Service
public class FeePayableServiceImpl extends ServiceImpl<FeePayableMapper, FeePayable> implements FeePayableService {
    private static final Logger LOGGER = LoggerFactory.getLogger(FeePayableServiceImpl.class);
    @Autowired
    private OmsUtil omsUtil;
    @Autowired
    private MdmUtil mdmUtil;
    @Autowired
    private TmsUtil tmsUtil;
    @Autowired
    private OtmUtil otmUtil;
    @Autowired
    private LspUtil lspUtil;
    @Autowired
    private CostMidService costMidService;

    @Autowired
    private ContractFleetDtlService contractFleetDtlService;

    @Autowired
    private ContractFinalpayService contractFinalpayService;

    @Autowired
    private FeeTypeService feeTypeService;

    @Autowired
    private StaPriceService staPriceService;

    @Autowired
    private PrepayBillService prepayBillService;

    @Autowired
    private PriceDeductRateService priceDeductRateService;

    @Autowired
    private PricePurchaseService pricePurchaseService;

    @Autowired
    private PricePurchaseDtlMapper pricePurchaseDtlMapper;

    @Autowired
    private BillDetailService billDetailService;

    @Autowired
    private ContractService contractService;

    @Autowired
    private QuoteService quoteService;

    @Autowired
    private QuoteDtlService quoteDtlService;

    @Autowired
    private AmgCstService amgCstService;

    @Autowired
    private WaybillStateService waybillStateService;

    @Autowired
    private TransTypeNameContrastService transTypeNameContrastService;

    @Autowired
    private PayApplyDtlBillService payApplyDtlBillService;

    @Autowired
    private SdBaseComputerService sdBaseComputerService;

    @Autowired
    private ICalcDriverCost calcDriverCost;

    @Autowired
    private HycApiUtil hycApiUtil;


    private final List<String> F_SUBCONTRACTOR_LSP = Lists.newArrayList(new String[]{
            "江西路易通达运输有限公司",
            "景德镇久顺途运输有限公司",
            "江西佳迅运输有限公司",
            "鹰潭运捷运输有限公司"
    });


    @Override
    public List<FeePayable> selectListNoTenant(Wrapper<FeePayable> ew) {
        return baseMapper.selectListNoTenant(ew);
    }

    @Override
    public List<FeePayableVO> selectPayableAndPriceDtlListNoTenant(Wrapper<FeePayable> ew) {
        return baseMapper.selectPayableAndPriceDtlListNoTenant(ew);
    }

    @Override
    public List<FeePayable> selectFeePayableList(Map<String, Object> condition) {
        Wrapper<FeePayable> feePayableWrapper = this.buildCondition(condition);
        return selectList(feePayableWrapper);
    }


    /**
     * 分页查询应付账款
     *
     * @param page
     */
    @Override
    public Page<FeePayable> queryFeePayablePage(Page<FeePayable> page) {
        if (page == null) {
            throw new BaseException("分页参数不为空");
        }
        Map<String, Object> cn = page.getCondition();
        Wrapper<FeePayable> ew = buildCondition(cn);
        ew.orderBy("gmt_create desc, id desc");
        List<FeePayable> feePayableList = baseMapper.selectPage(page, ew);
        page.setRecords(feePayableList);
        return page;
    }

    /**
     * 根据id查询应付账款
     */
    @Override
    public List<FeePayable> queryFeePayableByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BaseException("请选择指定信息");
        }
        return baseMapper.selectBatchIds(ids);
    }

    /**
     * 根据id查询应付账款
     */
    @Override
    public FeePayable queryFeePayableById(Long id) {
        if (ObjectUtils.isEmpty(id)) {
            throw new BaseException("请选择指定信息");
        }
        return this.selectById(id);
    }

    /**
     * 根据id查询应付账款总和信息
     */
    @Override
    public FeePayableHeaderVO queryFeePayableSumHeader(List<Long> ids) {
        EntityWrapper<FeePayable> feePayableEntityWrapper = new EntityWrapper<>();
        feePayableEntityWrapper.in("id", ids);
        return baseMapper.selectSumFeePayable(feePayableEntityWrapper);
    }

    private Wrapper<FeePayable> buildCondition(Map<String, Object> condition) {
        Wrapper<FeePayable> ew = new EntityWrapper<>();
        ew.orderBy("gmt_create desc, id desc");
        if (!Objects.isNull(condition) && !condition.isEmpty()) {
            //根据运单号查询
            Object passedIds = condition.get("passedIds");

            if (!StringUtils.isEmpty(passedIds)) {
                List ids = JSONArray.parseArray(passedIds.toString());
                if (CollectionUtils.isEmpty(ids)) {
                    ew.eq("id", null);
                } else {
                    ew.in("id", ids);
                }
            }
            Object unPassedIds = condition.get("unPassedIds");
            if (!StringUtils.isEmpty(unPassedIds)) {
                ew.notIn("id", JSONArray.parseArray(unPassedIds.toString()));
            }
            // 指令号
            Object orderCode = condition.get("orderCode");
            if (!StringUtils.isEmpty(orderCode)) {
                String[] oder = orderCode.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("order_code", oder);
            }
            Object orderCodes = condition.get("orderCodes");
            if (!StringUtils.isEmpty(orderCodes)) {
                //List<String> oder = (ArrayList<String>) orderCode;
                JSONArray orderList = JSONArray.parseArray(JSONObject.toJSONString(orderCodes));
                ew.in("order_code", orderList);
            }
            // 客户运单号
            Object cusWaybill = condition.get("cusWaybill");
            if (!StringUtils.isEmpty(cusWaybill)) {
                String[] oder = cusWaybill.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("cus_waybill", oder);
            }
            // 客户订单号
            Object cusOrderNo = condition.get("cusOrderNo");
            if (!StringUtils.isEmpty(cusOrderNo)) {
                String[] oder = cusOrderNo.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("cus_order_no", oder);
            }
            //根据装车单号查询
            Object waybillId = condition.get("waybillId");
            if (!StringUtils.isEmpty(waybillId)) {
                String[] oder = waybillId.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("waybill_id", oder);
            }
            // 多个系统运单号
            Object waybillDtlIdList = condition.get("waybillDtlIds");
            if (!StringUtils.isEmpty(waybillDtlIdList)) {
                String[] waybillDtlIdArray = waybillDtlIdList.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("waybill_dtl_id", waybillDtlIdArray);
            }
            //系统运单号eq
            Object waybillDtlId = condition.get("waybillDtlId");
            if (!StringUtils.isEmpty(waybillDtlId)) {
                ew.eq("waybill_dtl_id", waybillDtlId);
            }
            //系统运单号eq
            Object waybillDtlIds = condition.get("waybillDtlIds");
            if (!StringUtils.isEmpty(waybillDtlIds)) {
                String[] dtlIds = waybillDtlIds.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("waybill_dtl_id", dtlIds);
            }
            //根据客户ID查询
            Object payeeId = condition.get("payeeId");
            if (!StringUtils.isEmpty(payeeId)) {
                ew.eq("payee_id", payeeId.toString());
            }
            //根据承运商ID查询
            Object payerId = condition.get("payerId");
            if (!StringUtils.isEmpty(payerId)) {
                ew.eq("payer_id", payerId.toString());
            }
            //根据装车单时间段查询
            Object orderDate = condition.get("orderDate");
            if (!StringUtils.isEmpty(orderDate)) {
                ew.ge("order_date", orderDate);
            }
            Object orderDateB = condition.get("orderDateB");
            if (!StringUtils.isEmpty(orderDateB)) {
                ew.le("order_date", orderDateB);
            }
            Object receiptDate = condition.get("receiptDate");
            if (!StringUtils.isEmpty(receiptDate)) {
                ew.le("receipt_date", receiptDate);
            }
            Object vin = condition.get("vin");
            if (!StringUtils.isEmpty(vin)) {
                ew.eq("vin", vin);
            }
            Object vins = condition.get("vins");
            if (!StringUtils.isEmpty(vins)) {
                String[] vinArray = vins.toString().trim().replace(" ", "").split(",|;|\n");
                ew.in("vin", vinArray);
            }
            Object transTypeName = condition.get("transTypeName");
            if (!StringUtils.isEmpty(transTypeName)) {
                ew.eq("trans_type_name", transTypeName);
            }
            Object loadStatus = condition.get("loadStatus");
            if (!StringUtils.isEmpty(loadStatus)) {
                ew.eq("load_status", loadStatus);
            }
            Object startAddr = condition.get("startAddr");
            if (!StringUtils.isEmpty(startAddr)) {
                ew.eq("start_addr", startAddr);
            }
            Object endAddr = condition.get("endAddr");
            if (!StringUtils.isEmpty(endAddr)) {
                ew.eq("end_addr", endAddr);
            }
            Object status = condition.get("status");
            if (!StringUtils.isEmpty(status)) {
                ew.eq("status", status);
            } else {
                Integer[] statusArray = new Integer[]{0, 1};
                ew.in("status", statusArray);
            }
            Object fleetId = condition.get("fleetId");
            if (!StringUtils.isEmpty(fleetId)) {
                ew.eq("fleet_id", fleetId);
            }
            Object statusNot = condition.get("statusNot");
            if (!StringUtils.isEmpty(statusNot)) {
                ew.ne("status", statusNot);
            }
            Object priceType = condition.get("priceType");
            if (!StringUtils.isEmpty(priceType)) {
                if ((int) priceType == 0) {
                    ew.eq("actual_amt", 0);
                    ew.eq("est_amt", 0);
                }
                if ((int) priceType == 1) {
                    ew.eq("actual_amt", 0);
                    ew.ne("est_amt", 0);
                }
                if ((int) priceType == 2) {
                    ew.ne("actual_amt", 0);
                    //ew.ne("est_amt", 0);
                }
            }
//            if (!Objects.deepEquals("1", sourceSys)) {
//                ew.eq("source_sys", sourceSys);
//                ew.andNew().eq("trans_type_id", 6).or()
//                        .eq("trans_type_name", "人送地跑");
//            }else if(!StringUtils.isEmpty(sourceSys)){
//                ew.eq("source_sys", sourceSys);
//            }


            Object sourceSys = condition.get("sourceSys");
            Object isTransSourceType = condition.get("isTransSourceType");
            if (isTransSourceType != null) {
                if (Objects.deepEquals("0", sourceSys)) {
                    ew.eq("source_sys", sourceSys);
                    ew.andNew().eq("trans_type_id", 6).or()
                            .eq("trans_type_name", "人送地跑");
                } else if (Objects.deepEquals("1", sourceSys)) {
                    ew.eq("source_sys", sourceSys);
                } else if (Objects.deepEquals("2", sourceSys)) {
                    ew.eq("source_sys", 0);
                    ew.like("fleet_name", "临时");
                } else if (Objects.deepEquals("3", sourceSys)) {
                    ew.eq("source_sys", 0);
                } else {
                    ew.andNew().where(
                            "(source_sys = 0 AND trans_type_id=6) OR (source_sys = 0 AND trans_type_name = '人送地跑') OR source_sys=1"
                    );
                }
            } else {
                if (!StringUtils.isEmpty(sourceSys)) {
                    ew.eq("source_sys", sourceSys);
                }
            }


        }
        return ew;
    }

    /**
     * 同步生成应付账款
     *
     * @param shipParamDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String synchroCreateFeePayable(ShipParamDTO shipParamDTO) {
        boolean areCheckedTransType = false;
        //数据转换
        FeePayable feePayable = new FeePayable();
        feePayable.setVehicleTypeName(shipParamDTO.getPlateNo());       //车牌号
        feePayable.setWaybillId(shipParamDTO.getShipCode());
        feePayable.setWaybillDtlId(shipParamDTO.getOrderReleaseId());
        feePayable.setOrderCode(shipParamDTO.getShipmentId());
        feePayable.setTransTypeId(shipParamDTO.getTransTypeId());
        feePayable.setVehicleTypeCode(shipParamDTO.getVehicleName());   //车型
        feePayable.setVin(shipParamDTO.getVin());
        // 起点
        feePayable.setStartProvince(shipParamDTO.getOriginProvince());
        feePayable.setStartCity(shipParamDTO.getOriginCity());
        feePayable.setStartCounty(shipParamDTO.getOriginCounty());
        feePayable.setStartAddr(shipParamDTO.getOriginAddr());
        // 目的
        feePayable.setEndProvince(shipParamDTO.getDestProvince());
        feePayable.setEndCity(shipParamDTO.getDestCity());
        feePayable.setEndCounty(shipParamDTO.getDestCounty());
        feePayable.setEndAddr(shipParamDTO.getDestAddr());

        // feePayable.setOrderDate(shipParamDTO.getShipTime());
        // 2019-05-22 修改发运时间取值逻辑
        if (StringUtils.isEmpty(shipParamDTO.getOccurDate())) {
            feePayable.setOrderDate(shipParamDTO.getShipTime());
        } else {
            Date shipDate = ToolCommonUtils.getDateByStr(shipParamDTO.getOccurDate(), ToolCommonUtils.FORMAT_PARTTEN_ONE);
            if (Objects.nonNull(shipDate)) {
                feePayable.setOrderDate(shipDate);
            }
        }
        feePayable.setCusOrderNo(shipParamDTO.getCusOrderNo());
        feePayable.setCusWaybill(shipParamDTO.getCusWaybill());
        if (shipParamDTO.getProviderGid() == null) {
            throw new BaseException("providerGid不存在");
        }
        feePayable.setPayerId(Long.valueOf(shipParamDTO.getProviderGid()));
        //只处理四大家
        if (!F_SUBCONTRACTOR_LSP.contains(shipParamDTO.getProviderName())) {
            return null;
        }
        feePayable.setPayerName(shipParamDTO.getProviderName());
        if (shipParamDTO.getDriverGid() != null) {
            feePayable.setDriverId(Long.valueOf(shipParamDTO.getDriverGid()));
        }
        feePayable.setDriverName(shipParamDTO.getDriverName());
        feePayable.setEndCounty(shipParamDTO.getDestCounty());
        feePayable.setFleetName(shipParamDTO.getFleetName());
        if (shipParamDTO.getFleetId() != null) {
            feePayable.setFleetId(Long.valueOf(shipParamDTO.getFleetId()));
            LspFleetDTO fleetInfo = lspUtil.getFleetInfo(Long.valueOf(shipParamDTO.getFleetId()));
            if (fleetInfo != null && Objects.deepEquals(new Long(1), fleetInfo.getFleetTypeId())) {
                //自有车队
                return null;
            }
        }
        if (shipParamDTO.getTransTypeId() != null) {
            feePayable.setTransTypeId(shipParamDTO.getTransTypeId());
            TransportationTypeDTO transportTypeById = mdmUtil.getTransportTypeById(shipParamDTO.getTransTypeId());
            if (transportTypeById == null) {
                throw new BaseException("无效运输类型");
            }
            feePayable.setTransTypeName(transportTypeById.getOtmValue());
            if (Objects.deepEquals(feePayable.getTransTypeId(), 6) || (feePayable.getTransTypeName().indexOf("人送") >= 0)) {
                areCheckedTransType = true;
            }
        }
        if (shipParamDTO.getEventType() != null) {
            if ("BS_OP_DELIVERY".equals(shipParamDTO.getEventType())) {
                //10已发运
                feePayable.setLoadStatus("10");
            } else if ("BS_TRANS_ARRIVED".equals(shipParamDTO.getEventType())) {
                //30已运抵
                feePayable.setLoadStatus("30");
            }
        }
        if (areCheckedTransType) {
            Map<String, Object> map = new HashMap<>();
            map.put("orderCode", feePayable.getOrderCode());
            map.put("vin", feePayable.getVin());
            map.put("statusNot", 2);
            List<FeePayable> feePayables = this.selectListNoTenant(this.buildCondition(map));
            if (!CollectionUtils.isEmpty(feePayables)) {
                FeePayable updateFeePayable = new FeePayable();
                updateFeePayable.setId(feePayables.get(0).getId());
                // OR号
                if (!StringUtils.isEmpty(feePayable.getWaybillDtlId())) {
                    updateFeePayable.setWaybillDtlId(feePayable.getWaybillDtlId());
                }
                // 客户运单号
                if (!StringUtils.isEmpty(feePayable.getCusWaybill())) {
                    updateFeePayable.setCusWaybill(feePayable.getCusWaybill());
                }
                // 客户单号
                if (!StringUtils.isEmpty(feePayable.getCusOrderNo())) {
                    updateFeePayable.setCusOrderNo(feePayable.getCusOrderNo());
                }
                // 修改 - 针对可能已经出账但是会重新返回状态
                // updateFeePayable.setStatus(0);
                this.updateById(updateFeePayable);
                return null;
            }
        }
        return this.createFeePayable(feePayable, false, true);
    }

    /**
     * 根据部分应付账款数据创建应付账款信息与预付帐单
     *
     * @param feePayable
     */
    private String createFeePayable(FeePayable feePayable, boolean areBindException, boolean areUpdate) {
        try {
            feePayable.setNum(1);// 格式化数量
            //重复id绑定
            if (feePayable.getId() == null) {
                if (feePayable.getWaybillDtlId() != null) {
                    //如果 重复收取OR指定号运单将同步更新
                    EntityWrapper<FeePayable> feePayableEntityWrapper = new EntityWrapper<>();
                    feePayableEntityWrapper.eq("waybill_dtl_id", feePayable.getWaybillDtlId());
                    feePayableEntityWrapper.ne("status", 2);
                    feePayableEntityWrapper.orderBy("id desc");
                    List<FeePayable> feePayables = this.selectListNoTenant(feePayableEntityWrapper);
                    if (!CollectionUtils.isEmpty(feePayables)) {
                        feePayable.setId(feePayables.get(0).getId());
                        feePayable.setActualAmt(feePayables.get(0).getActualAmt());
                        feePayable.setActualPrice(feePayables.get(0).getActualPrice());
                        feePayable.setKilometre(feePayables.get(0).getKilometre());
                        feePayable.setContractCode(feePayables.get(0).getContractCode());
                        feePayable.setContractType(feePayables.get(0).getContractType());
                        feePayable.setQuoteId(feePayables.get(0).getQuoteId());
                    }
                }
            }

            /**
             * 绑定对应关联数据
             */
            //获取付款方信息
            LspBasicDTO lspById = lspUtil.getLspById(feePayable.getPayerId());
            if (lspById == null) {
                throw new BaseException("未匹配到指定付款方信息");
            }
            feePayable.setTenantId(lspById.getTenantId());
            if (feePayable.getCiamsId() == null) {
                //获取对应运单的客户
                List<ShipTaskDTO> otmShipmentDTL = otmUtil.getOtmShipmentDTL(feePayable.getOrderCode(), feePayable.getWaybillDtlId());
                if (CollectionUtils.isEmpty(otmShipmentDTL) || StringUtils.isEmpty(otmShipmentDTL.get(0).getCiamsId())) {
//					throw new BaseException("该运单无对应客户信息");
                } else {
                    // 起运名称
                    feePayable.setStartName(otmShipmentDTL.get(0).getOriginLocationName());
                    // 目的名称
                    feePayable.setEndName(otmShipmentDTL.get(0).getDestLocationName());

                    // 业务主体
                    feePayable.setCiamsId(otmShipmentDTL.get(0).getCiamsId());
                }
            } else if (StringUtils.isEmpty(feePayable.getStartName()) || StringUtils.isEmpty(feePayable.getEndName())) {
                List<ShipTaskDTO> otmShipmentDTL = otmUtil.getOtmShipmentDTL(feePayable.getOrderCode(), feePayable.getWaybillDtlId());
                if (!CollectionUtils.isEmpty(otmShipmentDTL)) {
                    // 起运名称
                    feePayable.setStartName(otmShipmentDTL.get(0).getOriginLocationName());
                    // 目的名称
                    feePayable.setEndName(otmShipmentDTL.get(0).getDestLocationName());
                }
            }
            /**
             * 绑定对应价格
             */
            // 根据分供方获取合同绑定价格信息
            if (feePayable.getFleetId() != null) {
                Contract contract = null;
                // boolean contractIsNull = true;
                //是否存在中间价绑定数据
                // if (feePayable.getStaPriceId() != null) {
                //     //绑定合同价
                //     if (feePayable.getActualPrice() == null || BigDecimal.ZERO.compareTo(feePayable.getActualPrice()) == 0) {
                //         contract = bindContractSource(feePayable);
                //     } else {
                //         contract = StringUtils.isEmpty(feePayable.getContractCode()) ? null : contractService.selectContractByCode(feePayable.getContractCode());
                //     }
                // }

                // 2019-06-24 计算人送供方价格
                sdBaseComputerService.computerFeePayableSendByDriver(feePayable);

                //绑定合同价
                if (feePayable.getActualPrice() == null || BigDecimal.ZERO.compareTo(feePayable.getActualPrice()) == 0) {
                    contract = bindContractSource(feePayable);
                } else {
                    contract = StringUtils.isEmpty(feePayable.getContractCode()) ? null : contractService.selectContractByCode(feePayable.getContractCode());
                }
                // if (contract == null) {
                // if (contract == null || feePayable.getActualPrice() == null || BigDecimal.ZERO.compareTo(feePayable.getActualPrice()) == 0) {

                // 2019-07-23 取消标准价
                // if (feePayable.getActualPrice() == null || BigDecimal.ZERO.compareTo(feePayable.getActualPrice()) == 0) {
                //
                //     OtmServiceResult stdPrice = otmUtil.getStdPrice(feePayable.getWaybillDtlId());
                //     if (stdPrice != null && "200".equals(stdPrice.getMessageCode())) {
                //         if (!StringUtils.isEmpty(stdPrice.getData())) {
                //             JSONObject.parseObject(stdPrice.getData());
                //             Map<String, Object> data = JSONObject.parseObject(stdPrice.getData(), Map.class);
                //             if (!CollectionUtils.isEmpty(data)) {
                //                 Object id = data.get("id");
                //                 feePayable.setStaPriceId((id == null) ? null : Long.parseLong(id.toString()));
                //
                //                 Object price = data.get("price");
                //                 feePayable.setEstPrice((price == null) ? null : new BigDecimal(price.toString()));
                //
                //                 Object miles = data.get("miles");
                //                 if (feePayable.getKilometre() == null || BigDecimal.ZERO.compareTo(feePayable.getKilometre()) == 0) {
                //                     feePayable.setKilometre((miles == null) ? null : new BigDecimal(miles.toString()));
                //                 }
                //             }
                //         }
                //     } else {
                //         if (areBindException) {
                //             throw new BaseException("OTM无标准价数据，请维护！");
                //         }
                //     }
                // }

                // formSumMoney(feePayable);
                //去除价格里程的空值
                if (Objects.isNull(feePayable.getKilometre())) {
                    feePayable.setKilometre(BigDecimal.ZERO);
                }
                if (Objects.isNull(feePayable.getActualPrice())) {
                    feePayable.setActualPrice(BigDecimal.ZERO);
                }
                if (Objects.isNull(feePayable.getEstPrice())) {
                    feePayable.setEstPrice(BigDecimal.ZERO);
                }
                if (Objects.isNull(feePayable.getActualAmt()) || BigDecimal.ZERO.compareTo(feePayable.getActualAmt()) == 0) {
                    feePayable.setActualAmt(feePayable.getKilometre().multiply(feePayable.getActualPrice()));
                }
                feePayable.setEstAmt(feePayable.getKilometre().multiply(feePayable.getEstPrice()));
                if (contract != null) {
                    List<ContractFleetDtl> contractFleetDtls = contractFleetDtlService.selectContractFleetDtlByContract(contract);
                    // 计算油卡和现金比例
                    computeOilRate(contractFleetDtls, feePayable, contract);
                }
                try {
                    //根据车架号修改支付价格
                    if (feePayable.getVin() != null && feePayable.getActualPrice() != null && feePayable.getActualPrice().compareTo(BigDecimal.ZERO) > 0) {
                        pricePurchaseService.updateExtPurchasePriceByItemUidNoTenant(feePayable);
                    }
                } catch (BaseException e) {
                    feePayable.setActualPrice(BigDecimal.ZERO);
                    feePayable.setEstPrice(BigDecimal.ZERO);
                    feePayable.setKilometre(BigDecimal.ZERO);
                    feePayable.setActualAmt(BigDecimal.ZERO);
                    feePayable.setEstAmt(BigDecimal.ZERO);
                    throw e;
                }
                if (areUpdate) {
                    this.insertOrUpdate(feePayable);
                }
                // 生成预付帐单
                // prepayBillService.insertPrepayBill(feePayable, contract);
                prepayBillService.createPrepayBillByContract(feePayable, contract);
            } else {
                throw new BaseException("无车队信息");
            }
        } catch (BaseException e) {
            LOGGER.error("FeePayableServiceImpl.createFeePayable ERROR: {}", e.getMessage());
            if (areBindException) {
                throw e;
            } else {
                this.insertOrUpdate(feePayable);
            }
            return e.getMessage();
        } catch (Exception e) {
            LOGGER.error("FeePayableServiceImpl.createFeePayable ERROR: {}", e.getMessage());
            if (areBindException) {
                throw e;
            } else {
                this.insertOrUpdate(feePayable);
            }
            return e.getMessage();
        }
        return null;
    }

    /**
     * otm同步价格
     *
     * @param feePayable
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateExtPurchasePriceByItemUidNoTenant(FeePayable feePayable) {
        //根据车架号修改支付价格
        pricePurchaseService.updateExtPurchasePriceByItemUidNoTenant(feePayable);
    }

    /**
     * 计算油卡和现金比例
     *
     * @param contractFleetDtls
     * @param feePayable
     * @param contract
     */
    @Override
    public Multimap<String, BigDecimal> computeOilRate(List<ContractFleetDtl> contractFleetDtls, FeePayable feePayable, Contract contract) {
        if (!CollectionUtils.isEmpty(contractFleetDtls)) {
            Multimap<String, BigDecimal> resultMap = LinkedListMultimap.create();
            for (ContractFleetDtl contractFleetDtl : contractFleetDtls) {
                if (Objects.deepEquals(feePayable.getFleetId(), contractFleetDtl.getFleetId())) {
                    BigDecimal oilFinalpayRate = contractFleetDtl.getOilFinalpayRate();
                    if (oilFinalpayRate == null) {
                        oilFinalpayRate = BigDecimal.ZERO;
                    }
                    BigDecimal cashFinalpayRate = contractFleetDtl.getCashFinalpayRate();
                    if (cashFinalpayRate == null) {
                        cashFinalpayRate = BigDecimal.ZERO;
                    }
                    if (contract.getContractType() == 0) {
                        //临时合同
                        Integer countByOrderCode = getCountByOrderCode(feePayable.getOrderCode());
                        if (!Integer.valueOf(0).equals(countByOrderCode)) {
                            // 计算比例
                            BigDecimal countRate = BigDecimal.valueOf(countByOrderCode);
                            // 油费
                            resultMap.put(feePayable.getOrderCode(), oilFinalpayRate);
                            // 现金
                            resultMap.put(feePayable.getOrderCode(), cashFinalpayRate);
                            feePayable.setOilBaPay(
                                    oilFinalpayRate.divide(countRate, 6, BigDecimal.ROUND_HALF_UP)
                                            .setScale(2, BigDecimal.ROUND_HALF_UP));
                            feePayable.setCashBaPay(
                                    cashFinalpayRate.divide(countRate, 6, BigDecimal.ROUND_HALF_UP)
                                            .setScale(2, BigDecimal.ROUND_HALF_UP));
                        } else {
                            feePayable.setOilBaPay(oilFinalpayRate);
                            // 现金尾款
                            feePayable.setCashBaPay(cashFinalpayRate);
                        }
                    } else if (contract.getContractType() == 1) {
                        //正式合同
                        feePayable.setOilBaPay(feePayable.getActualAmt().multiply(oilFinalpayRate == null ? BigDecimal.ZERO : oilFinalpayRate));
                        // 现金尾款
                        feePayable.setCashBaPay(feePayable.getActualAmt().multiply(cashFinalpayRate == null ? BigDecimal.ZERO : cashFinalpayRate));
                    }
                }
            }
            return resultMap;
        }
        return null;
    }

    /**
     * 更新客户
     *
     * @param condition
     */
    @Override
    public void updateCiamsId(Map<String, Object> condition) {
        Set<String> shipmentIdSet = new HashSet<>();
        Wrapper<FeePayable> feePayableWrapper = buildCondition(condition);

        feePayableWrapper.andNew().eq("ciamsId", "").or().isNull("ciamsId");
        List<FeePayable> feePayables = selectListNoTenant(feePayableWrapper);
        LOGGER.info("CiamsAreNull Size:{}", feePayables.size());
        feePayables.forEach(feePayable -> {
            shipmentIdSet.add(feePayable.getOrderCode());
        });

        Map<String, Map<String, String>> shipmentIdAndCiamsMap = new HashMap<>();
        shipmentIdSet.forEach(s -> {
            ShipmentDTO otmShipmentDTL = otmUtil.getOtmShipment(s);
            if (otmShipmentDTL != null && !CollectionUtils.isEmpty(otmShipmentDTL.getShipTaskDTOList())) {
                HashMap<String, String> wayBillDtlAndCiamsNameMap = new HashMap<>();
                otmShipmentDTL.getShipTaskDTOList().forEach(shipTaskDTO -> {
                    wayBillDtlAndCiamsNameMap.put(shipTaskDTO.getTaskId(), shipTaskDTO.getCiamsId());
                    wayBillDtlAndCiamsNameMap.put("startName", shipTaskDTO.getOriginLocationName());
                    wayBillDtlAndCiamsNameMap.put("endName", shipTaskDTO.getDestLocationName());
                });
                shipmentIdAndCiamsMap.put(s, wayBillDtlAndCiamsNameMap);
            }
        });
        List<FeePayable> updateFeePayables = new ArrayList<>();
        feePayables.forEach(feePayable -> {
            if (shipmentIdAndCiamsMap.containsKey(feePayable.getOrderCode())) {
                String s = shipmentIdAndCiamsMap.get(feePayable.getOrderCode()).get(feePayable.getWaybillDtlId());
                feePayable.setCiamsId(s);
                // 起运名称
                feePayable.setStartName(shipmentIdAndCiamsMap.get(feePayable.getOrderCode()).get("startName"));
                // 目的名称
                feePayable.setEndName(shipmentIdAndCiamsMap.get(feePayable.getOrderCode()).get("endName"));
                updateFeePayables.add(feePayable);
            }
        });
        if (!CollectionUtils.isEmpty(updateFeePayables)) {
            this.updateBatchById(updateFeePayables);
        }
    }

    /**
     * 判断是否可以出账
     *
     * @param idList
     */
    @Override
    public FeePermissCommonVO queryPermissOrderCode(Long[] idList) {
        List<FeePayablePermissVO> feePayablePermissVOList = baseMapper.queryFeePayblePermiss(Arrays.asList(idList));
        if (!CollectionUtils.isEmpty(feePayablePermissVOList)) {
            FeePermissCommonVO commonVO = new FeePermissCommonVO();
            List<String> msgList = Lists.newArrayList();
            feePayablePermissVOList.forEach(fee -> {
                //StringBuilder sb = new StringBuilder();
                //sb.append("指令号:").append(fee.getOrderCode()).append(":").append("这个指令下存在未回单的数据, 不可出账!");
                //msgList.add(sb.toString());
                msgList.add(fee.getOrderCode());
            });
            commonVO.setOrderCodeList(msgList);
            if (!CollectionUtils.isEmpty(msgList)) {
                List<Long> feeIdList = Lists.newArrayList();
                EntityWrapper<FeePayable> ew = new EntityWrapper<>();
                ew.in("order_code", msgList);
                ew.eq("load_status", "20");
                ew.ne("actual_amt", 0);
                ew.setSqlSelect("id");
                List<Object> objectList = selectObjs(ew);
                if (!CollectionUtils.isEmpty(objectList)) {
                    objectList.forEach(obj -> {
                        feeIdList.add(Long.parseLong(obj.toString()));
                    });
                    commonVO.setIdList(feeIdList);
                }
            }
            return commonVO;
        }
        return null;
    }

    /**
     * 获取人送的订单 - 没有OR号的
     *
     * @return
     */
    @Override
    public List<FeePayable> updateSendDriverFeePayable() {
        // 获取需要更新的数据
        List<FeePayable> feePayableList = getPayableListByConditon();
        if (!CollectionUtils.isEmpty(feePayableList)) {
            List<FeePayable> updateFeeList = Lists.newArrayList();
            feePayableList.forEach(feePayable -> {
                ShipmentDTO otmShipment = otmUtil.getOtmShipment(feePayable.getOrderCode());
                if (otmShipment != null && !CollectionUtils.isEmpty(otmShipment.getShipTaskDTOList())) {
                    // // 发运时间
                    // if (feePayable.getOrderDate() == null && otmShipment.getExpcetShipDate() != null) {
                    //     feePayable.setOrderDate(otmShipment.getExpcetShipDate());
                    // }
                    for (ShipTaskDTO shipTaskDTO : otmShipment.getShipTaskDTOList()) {
                        if (shipTaskDTO.getVin() != null && shipTaskDTO.getVin().equals(feePayable.getVin())) {
                            updateFeePayableByTaskDto(shipTaskDTO, feePayable);
                            updateFeeList.add(feePayable);
                            continue;
                        }
                    }
                    // 更新预付的客户运单号
                    if (!StringUtils.isEmpty(feePayable.getCusWaybill())) {
                        EntityWrapper<PrepayBill> prebillEw = new EntityWrapper<>();
                        prebillEw.eq("head_id", feePayable.getId());
                        PrepayBill prepayBill = new PrepayBill();
                        if (!StringUtils.isEmpty(feePayable.getCusWaybill())) {
                            prepayBill.setCusWaybill(feePayable.getCusWaybill());
                        }
                        if (!StringUtils.isEmpty(feePayable.getWaybillDtlId())) {
                            prepayBill.setWaybillDtlId(feePayable.getWaybillDtlId());
                        }
                        prepayBillService.update(prepayBill, prebillEw);
                    }
                } else {
                    // 没有明细
                    feePayable.setUpCusNum(feePayable.getUpCusNum() + 1);
                }
            });
            // 更新
            if (!CollectionUtils.isEmpty(updateFeeList)) {
                this.updateBatchById(updateFeeList);
            }
        }
        return null;
    }

    /**
     * 根据指令号获取对应的账款总油费和现金费用
     *
     * @param orderCode
     * @return
     */
    @Override
    public FeePayable selectCashAndOilSumNoTenant(String orderCode) {
        if (!StringUtils.isEmpty(orderCode)) {
            List<FeePayable> feePayableList = baseMapper.selectCashAndOilSumNoTenant(orderCode);
            if (!CollectionUtils.isEmpty(feePayableList)) {
                FeePayable feePayable = feePayableList.get(0);
                if (feePayable.getCashBaPay() == null) {
                    feePayable.setCashBaPay(BigDecimal.ZERO);
                }
                if (feePayable.getOilBaPay() == null) {
                    feePayable.setOilBaPay(BigDecimal.ZERO);
                }
                return feePayable;
            }
        }
        return null;
    }

    /**
     * 如果正常发运, 更新慧运车未发运的数据
     *
     * @param orderCode
     */
    @Override
    public void updateHuiyuncheLoadStatusByOrderCode(String orderCode) {
        if (!StringUtils.isEmpty(orderCode)) {
            baseMapper.updateHuiyuncheLoadStatusByOrderCode(orderCode);
            // 更新预付账单的发运状态
            prepayBillService.updateHuiyuncheLoadStatusByOrderCode(orderCode);
        }
    }

    /**
     * 根据支付申请id集合获取对应下的应付账款
     *
     * @param payApplyIds
     * @return
     */
    @Override
    public List<FeePayable> queryFeePayableListByPayApplyIdList(Collection<Long> payApplyIds) {
        if (CollectionUtils.isEmpty(payApplyIds)) {
            return null;
        }
        // 找到对应的明细
        List<PayApplyDtlBill> payApplyDtlBillList = payApplyDtlBillService.queryPayApplyDtlListByHeadIdList(payApplyIds);
        if (CollectionUtils.isEmpty(payApplyDtlBillList)) {
            return null;
        }
        Set<Long> billIdSet = new HashSet<>();
        payApplyDtlBillList.forEach(dtl -> {
            billIdSet.add(dtl.getBilId());
        });
        if (CollectionUtils.isEmpty(billIdSet)) {
            return null;
        }
        List<BillDetail> billDetailList = billDetailService.getBillDetailList(new ArrayList<>(billIdSet));
        if (CollectionUtils.isEmpty(billDetailList)) {
            return null;
        }
        Set<Long> feePayableIdSet = new HashSet<>();
        billDetailList.forEach(billDtl -> {
            feePayableIdSet.add(billDtl.getFeeId());
        });
        if (CollectionUtils.isEmpty(feePayableIdSet)) {
            return null;
        }
        return this.selectBatchIds(new ArrayList<>(feePayableIdSet));
    }

    /**
     * 修改数据
     *
     * @param tmsReleaseDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateFeePayableForTms(TmsReleaseDto tmsReleaseDto) {
        if (Objects.isNull(tmsReleaseDto)) {
            throw new BaseException("参数为空");
        }
        if (StringUtils.isEmpty(tmsReleaseDto.getShipmentGid())) {
            throw new BaseException("指令号不能为空");
        }
        if (StringUtils.isEmpty(tmsReleaseDto.getReleaseGid())) {
            throw new BaseException("系统运单号不能为空");
        }
        EntityWrapper<FeePayable> ew = new EntityWrapper<>();
        ew.eq("order_code", tmsReleaseDto.getShipmentGid());
        ew.eq("waybill_dtl_id", tmsReleaseDto.getReleaseGid());
        List<FeePayable> feePayableList = this.selectListNoTenant(ew);
        if (!CollectionUtils.isEmpty(feePayableList)) {
            FeePayable feePayable = feePayableList.get(0);
            // 判断是否出账
            boolean isUpdatePrice = false;
            if (Integer.valueOf(0).equals(feePayable.getStatus())) {
                // 业务主体
                if (!StringUtils.isEmpty(tmsReleaseDto.getCiamsId())) {
                    isUpdatePrice = true;
                    feePayable.setCiamsId(tmsReleaseDto.getCiamsId());
                }
                // 客户订单号
                if (!StringUtils.isEmpty(tmsReleaseDto.getCusOrderNo())) {
                    feePayable.setCusOrderNo(tmsReleaseDto.getCusOrderNo());
                }
                // 客户运单号
                if (!StringUtils.isEmpty(tmsReleaseDto.getCusWaybillNo())) {
                    feePayable.setCusWaybill(tmsReleaseDto.getCusWaybillNo());
                }
                // 车架号
                if (!StringUtils.isEmpty(tmsReleaseDto.getVin())) {
                    feePayable.setVin(tmsReleaseDto.getVin());
                }
                if (isUpdatePrice) {
                    this.updateFeePayablePrice(feePayable.getId());
                    this.updateById(feePayable);
                } else {
                    // 更新账款数据
                    this.updateById(feePayable);
                }
            }
            // 获取对应的价格信息和预付账单信息
            PricePurchase pricePurchase = pricePurchaseService.getPricePurchaseByShipmentCode(feePayable.getWaybillId());
            if (Objects.nonNull(pricePurchase)) {
                // 车架号
                if (!StringUtils.isEmpty(tmsReleaseDto.getVin())) {
                    pricePurchase.setItemUid(tmsReleaseDto.getVin());
                }
                // 客户运单号
                if (!StringUtils.isEmpty(tmsReleaseDto.getCusWaybillNo())) {
                    pricePurchase.setCusWaybill(tmsReleaseDto.getCusWaybillNo());
                }
                // 更新价格数据
                pricePurchaseService.updateById(pricePurchase);
            }
            // 更新预付账单
            EntityWrapper<PrepayBill> prepayBillEw = new EntityWrapper<>();
            prepayBillEw.eq("head_id", feePayable.getId());
            List<PrepayBill> prepayBillList = prepayBillService.selectListNoTenant(prepayBillEw);
            if (!CollectionUtils.isEmpty(prepayBillList)) {
                prepayBillList.forEach(prepayBill -> {
                    // 车架号
                    prepayBill.setVin(feePayable.getVin());
                    // 客户运单号
                    prepayBill.setCusWaybill(feePayable.getCusWaybill());
                    // 客户订单号
                });
                // 更新预付信息
                prepayBillService.updateBatchById(prepayBillList);
            }
        }
    }

    @Override
    public List<JSONObject> getHuiyunchePrice(List<String> sysWaybillIdList) {
        try {
            if (!CollectionUtils.isEmpty(sysWaybillIdList)) {
                List<JSONObject> resultObjList = Lists.newArrayList();
                EntityWrapper<FeePayable> ew = new EntityWrapper<>();
                ew.in("waybill_dtl_id", sysWaybillIdList);
                List<FeePayable> feePayableList = baseMapper.selectListNoTenant(ew);
                if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(feePayableList)) {
                    for (FeePayable feePayable : feePayableList) {

                        Date shipmentDate = feePayable.getOrderDate();
                        if (Objects.isNull(shipmentDate)) {
                            shipmentDate = ToolCommonUtils.getDateByStr("2019-08-07 11:30:00", "yyyy-MM-dd hh:mm:ss");
                        }
                        EntityWrapper<PricePurchaseVO> priceEw = new EntityWrapper<>();
                        priceEw.eq("orderlineId", feePayable.getOrderCode());
                        List<PricePurchaseDtl> updatePriceDtlNoTenant = pricePurchaseDtlMapper.getUpdatePriceDtlNoTenant(priceEw);
                        if (!CollectionUtils.isEmpty(updatePriceDtlNoTenant)) {
                            shipmentDate = updatePriceDtlNoTenant.get(0).getCurrentEffectDate();
                        }
                        Map<Integer, Object> resultMap = calcDriverCost.getWaybillCostByCalc(feePayable.getVehicleClassifyId(), feePayable.getStartProvince(),
                                feePayable.getStartCity(), feePayable.getEndProvince(), feePayable.getEndCity(), null, shipmentDate);

                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("指令号", feePayable.getOrderCode());
                        jsonObject.put("系统运单号", feePayable.getWaybillDtlId());

                        Set<Integer> keySet = resultMap.keySet();
                        keySet.forEach(keyS -> {
                            DWaybillFeeEnum byValue = DWaybillFeeEnum.getByValue(keyS);
                            jsonObject.put(byValue.getText(), resultMap.get(keyS));
                        });
                        BigDecimal sumCost = new BigDecimal(resultMap.get(10).toString());
                        BigDecimal killmon = new BigDecimal(resultMap.get(90).toString());
                        BigDecimal actPrice = sumCost.divide(killmon, BigDecimal.ROUND_HALF_UP);
                        BigDecimal actPrice4 = sumCost.divide(killmon, 4, BigDecimal.ROUND_HALF_UP);
                        jsonObject.put("单价_2", actPrice);
                        jsonObject.put("单价_4", actPrice4);
                        resultObjList.add(jsonObject);
                    }
                }
                return resultObjList;
            }
        } catch (Exception e) {
            LOGGER.error("getHuiyunchePrice error: {}", e);
        }
        return null;
    }

    /**
     * 更新慧运车信息
     *
     * @param feeIdList
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateHycData(List<Long> feeIdList) {
        if (CollectionUtils.isEmpty(feeIdList)) {
            throw new BaseException("请选择数据");
        }
        List<FeePayable> feePayableList = this.selectBatchIds(feeIdList);
        if (!CollectionUtils.isEmpty(feePayableList)) {
            Set<String> orderCodeSet = Sets.newHashSet();
            feePayableList.forEach(feePayable -> {
                orderCodeSet.add(feePayable.getOrderCode());
            });

            List<HycOrderData> hycDataList = hycApiUtil.getHycDataByOrderCode(orderCodeSet);
            EntityWrapper<FeePayable> ew = new EntityWrapper<>();
            hycDataList.forEach(hycOrderData -> {
                // 更新字段
                ew.eq("order_code", hycOrderData.getOrderCode());

                FeePayable updateFeePayable = new FeePayable();
                // 起运省
                updateFeePayable.setStartProvince(hycOrderData.getDepartureProvince());
                // 起运市
                updateFeePayable.setStartCity(hycOrderData.getDepartureCity());
                // 目的省
                updateFeePayable.setEndProvince(hycOrderData.getDestProvince());
                // 目的市
                updateFeePayable.setEndCity(hycOrderData.getDestCity());
                // 发运时间
                if (!StringUtils.isEmpty(hycOrderData.getOutsetTime())) {
                    updateFeePayable.setOrderDate(ToolCommonUtils.getDateByStr(hycOrderData.getOutsetTime(), ToolCommonUtils.FORMAT_PARTTEN_2));
                }
                this.update(updateFeePayable, ew);
            });
        }

    }


    /**
     * 更新指令信息
     *
     * @param shipTaskDTO
     * @param feePayable
     */
    private void updateFeePayableByTaskDto(ShipTaskDTO shipTaskDTO, FeePayable feePayable) {
        // OR号
        if (StringUtils.isEmpty(feePayable.getWaybillDtlId()) && !StringUtils.isEmpty(shipTaskDTO.getTaskId())) {
            feePayable.setWaybillDtlId(shipTaskDTO.getTaskId());
        }
        // 客户运单号
        if (StringUtils.isEmpty(feePayable.getCusWaybill()) && !StringUtils.isEmpty(shipTaskDTO.getCusWaybillNo())) {
            feePayable.setCusWaybill(shipTaskDTO.getCusWaybillNo());
        } else if (StringUtils.isEmpty(shipTaskDTO.getCusWaybillNo())) {
            feePayable.setUpCusNum(feePayable.getUpCusNum() + 1);
        }
        // 业务主体
        if (StringUtils.isEmpty(feePayable.getCiamsId()) && !StringUtils.isEmpty(shipTaskDTO.getCiamsId())) {
            feePayable.setCiamsId(shipTaskDTO.getCiamsId());
        }
        // 发运时间
        // if (feePayable.getOrderDate() == null && shipTaskDTO.getExpcetShipDate() != null) {
        // 	feePayable.setOrderDate(shipTaskDTO.getExpcetShipDate());
        // }
    }

    /**
     * 获取需要更新的数据
     *
     * @return
     */
    private List<FeePayable> getPayableListByConditon() {
        Page<FeePayable> page = new Page<>();
        page.setCurrent(1);
        page.setSize(50);
        EntityWrapper<FeePayable> ew = new EntityWrapper<>();
        ew.orderBy("id asc");
        ew.eq("trans_type_name", "人送地跑");
        ew.eq("source_sys", "0");
        ew.lt("up_cus_num", 3);
        ew.isNull("cus_waybill");
        return baseMapper.selectPageNoTenant(page, ew);
    }

    /**
     * 根据指令号获取对应的数量
     *
     * @param orderCode
     * @return
     */
    @Override
    public Integer getCountByOrderCode(String orderCode) {
        if (!StringUtils.isEmpty(orderCode)) {
            EntityWrapper<FeePayable> ew = new EntityWrapper<>();
            ew.eq("order_code", orderCode);
            return this.selectCount(ew);
        }
        return 0;
    }

    /**
     * 获取发运状态为10的应付账单
     */
    @Override
    @Transactional
    public void updateFeePayableByRouteMode(List<FeePayable> feePayables) {
        if (CollectionUtils.isEmpty(feePayables)) {
            EntityWrapper<FeePayable> feePayableEntityWrapper = new EntityWrapper<>();
            feePayableEntityWrapper.eq("load_status", "10");
            feePayables = this.selectListNoTenant(feePayableEntityWrapper);
        }
        if (!CollectionUtils.isEmpty(feePayables)) {
            Set<String> waybillDtlIdSet = new HashSet<>();
            // Set<String> orderCodeSet = new HashSet<>();
            LOGGER.info("updateFeePayableByRouteMode#Service\nMsg: Exist\tFeePayable-->Size:{}", feePayables.size());
            feePayables.forEach(feePayable -> {
                // if (Objects.deepEquals(feePayable.getTransTypeId(), 6) || (feePayable.getTransTypeName().indexOf("人送") >= 0)) {
                //     orderCodeSet.add("ULC/ZC." + feePayable.getOrderCode());
                // } else {
                //     waybillDtlIdSet.add("ULC/ZC." + feePayable.getWaybillDtlId());
                // }
                if (!StringUtils.isEmpty(feePayable.getWaybillDtlId())) {
                    waybillDtlIdSet.add("ULC/ZC." + feePayable.getWaybillDtlId());
                }
                // else if (!StringUtils.isEmpty(feePayable.getOrderCode())) {
                //     orderCodeSet.add("ULC/ZC." + feePayable.getOrderCode());
                // }
            });
            // List<String> existAttribute = waybillStateService.selectCheckedAttribute(new ArrayList<>(orderCodeSet));
            List<String> existReleaseGid = waybillStateService.selectCheckedOrderReleaseGid(new ArrayList<>(waybillDtlIdSet));

            // LOGGER.info("updateFeePayableByRouteMode#Service\nMsg: Attribute-->Size:{}\nMsg: ReleaseGid-->Size:{}", existAttribute.size(), existReleaseGid.size());
            List<FeePayable> updateFee = new ArrayList<>();
            feePayables.forEach(feePayable -> {
                // if (Objects.deepEquals(feePayable.getTransTypeId(), 6) || (feePayable.getTransTypeName().indexOf("人送") >= 0)) {
                //     if (existAttribute.contains("ULC/ZC." + feePayable.getOrderCode())) {
                //         feePayable.setLoadStatus("20");
                //         updateFee.add(feePayable);
                //     }
                // } else {
                //     if (existReleaseGid.contains("ULC/ZC." + feePayable.getWaybillDtlId())) {
                //         feePayable.setLoadStatus("20");
                //         updateFee.add(feePayable);
                //     }
                // }
                // if (!CollectionUtils.isEmpty(existAttribute) && existAttribute.size() > 0) {
                //     if (existAttribute.contains("ULC/ZC." + feePayable.getOrderCode())) {
                //         feePayable.setLoadStatus("20");
                //         updateFee.add(feePayable);
                //     }
                // }
                if (!CollectionUtils.isEmpty(existReleaseGid) && existReleaseGid.size() > 0) {
                    if (existReleaseGid.contains("ULC/ZC." + feePayable.getWaybillDtlId())) {
                        feePayable.setLoadStatus("20");
                        updateFee.add(feePayable);
                    }
                }
            });

            if (!CollectionUtils.isEmpty(updateFee)) {
                LOGGER.info("updateFeePayableByRouteMode#Service\nMsg: UpdateLoadStatus");
                this.updateBatchById(updateFee);
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<FeePayable> updateAppointFeePayableByRouteMode(List<Long> ids) {
        List<FeePayable> feePayables = new ArrayList<>();
        if (CollectionUtils.isEmpty(ids)) {
            return null;
        }
        //修找对应id的数据获取对应运单号
        EntityWrapper<FeePayable> appointFeePayableEntityWrapper = new EntityWrapper<>();
        appointFeePayableEntityWrapper.in("id", ids);
        List<FeePayable> appointFeePayables = this.selectListNoTenant(appointFeePayableEntityWrapper);
        Set<String> waybillDtlId = new HashSet<>();
        Set<String> orderReleaseSet = new HashSet<>();

        if (!CollectionUtils.isEmpty(appointFeePayables)) {
            appointFeePayables.forEach(feePayable -> {
                waybillDtlId.add(feePayable.getWaybillDtlId());
                orderReleaseSet.add("ULC/ZC." + feePayable.getWaybillDtlId());
            });
            // 第一步: 查询运单表中是否有数据
            // 对otm没有的数据进行插入, 存在的就更新最新的数据
            this.updateOtmStateData(orderReleaseSet);

            //根据指定运单号更新发运状态
            EntityWrapper<FeePayable> feePayableEntityWrapper = new EntityWrapper<>();
            feePayableEntityWrapper.in("waybill_dtl_id", waybillDtlId);
            feePayableEntityWrapper.eq("load_status", "10");
            feePayables = this.selectListNoTenant(feePayableEntityWrapper);
            this.updateFeePayableByRouteMode(feePayables);
        }


        return feePayables;
    }

    /**
     * 插入或更新
     *
     * @param orderReleaseSet
     */
    private void updateOtmStateData(Set<String> orderReleaseSet) {
        if (!CollectionUtils.isEmpty(orderReleaseSet)) {
            List<OrderReleaseStatueDto> orderReleaseStatueDtoAllLis = Lists.newArrayList();
            if (orderReleaseSet.size() > 100) {
                List<String> newList = Lists.newArrayList();
                newList.addAll(orderReleaseSet);
                List<List<String>> paramList = BmsCollectionUtils.subListByNum(newList, 100);
                paramList.forEach(param -> {
                    List<OrderReleaseStatueDto> paramResultList = this.getOtmResult(param);
                    if (!CollectionUtils.isEmpty(paramResultList)) {
                        orderReleaseStatueDtoAllLis.addAll(paramResultList);
                    }
                });
            } else {
                List<OrderReleaseStatueDto> orderReleaseStatueDtoList = this.getOtmResult(orderReleaseSet);
                if (!CollectionUtils.isEmpty(orderReleaseStatueDtoList)) {
                    orderReleaseStatueDtoAllLis.addAll(orderReleaseStatueDtoList);
                }
            }


            if (!CollectionUtils.isEmpty(orderReleaseStatueDtoAllLis)) {
                List<WaybillState> waybillStateList = Lists.newArrayList();
                orderReleaseStatueDtoAllLis.forEach(otmOrder -> {
                    WaybillState waybillState = new WaybillState();
                    // 运单号
                    waybillState.setOrderReleaseGid(otmOrder.getOrder_release_gid());
                    // 路由模式名称
                    waybillState.setRouteModeName(otmOrder.getRoute_mode_name());
                    // 运单类型
                    waybillState.setAttribute3(otmOrder.getAttribute3());
                    // 指令号
                    waybillState.setAttribute16(otmOrder.getAttribute16());
                    // 运单状态
                    waybillState.setDescription(otmOrder.getDescription());
                    // 末段状态
                    waybillState.setPodStatus(otmOrder.getPod_status());
                    // 起运地
                    waybillState.setOmsDest(otmOrder.getOms_dest());
                    // 目的地
                    waybillState.setDestLocationGid(otmOrder.getDest_location_gid());
                    // 更新时间
                    if (!StringUtils.isEmpty(otmOrder.getUpdate_date())) {
                        waybillState.setUpdateDate(ToolCommonUtils.getDateByStr(otmOrder.getUpdate_date(), ToolCommonUtils.FORMAT_PARTTEN_4));
                    }
                    waybillStateList.add(waybillState);
                });
                if (!CollectionUtils.isEmpty(waybillStateList)) {
                    waybillStateService.insertOrUpdateBatch(waybillStateList);
                }
            }
        }
    }

    private List<OrderReleaseStatueDto> getOtmResult(Collection<String> orderReleaseSet) {
        String orderReleaseIds = org.apache.commons.lang3.StringUtils.join(orderReleaseSet, ",");
        OtmServiceResult otmServiceResult = otmUtil.queryBatchOrderReleaseStatus(orderReleaseIds);
        if (Objects.nonNull(otmServiceResult) && !StringUtils.isEmpty(otmServiceResult.getData())) {
            return JSONArray.parseArray(otmServiceResult.getData(), OrderReleaseStatueDto.class);
        }
        return null;
    }

    /**
     * 获取对应 id集合
     *
     * @param page
     * @return
     */
    @Override
    public List<Object> queryFeePayableIdList(Page<FeePayable> page) {
        Map<String, Object> cn = page.getCondition();
        Wrapper<FeePayable> ew = buildCondition(cn);
        ew.orderBy("gmt_create desc, id desc");
        ew.setSqlSelect("id");
        return baseMapper.selectObjs(ew);
    }

    /**
     * 根据id集合
     *
     * @param page
     * @return
     */
    @Override
    public Page<FeePayable> queryFeePayablePageByIds(Page<CommonVO> page) {
        Page<FeePayable> feePayablePage = new Page<>();
        BeanUtils.copyProperties(page, feePayablePage);
        EntityWrapper<FeePayable> ew = new EntityWrapper<>();
        ew.in("id", JSONArray.parseArray(page.getCondition().get("ids").toString()));
        feePayablePage.setRecords(baseMapper.selectPage(feePayablePage, ew));
        return feePayablePage;
    }

    /**
     * 自动更新应付账款
     *
     * @param id
     */
    @Override
    public void updateFeePayablePrice(Long id) {
        try {
            /*
             * 获取价格为0或为空值的数据
             */
            EntityWrapper<FeePayable> ew = new EntityWrapper<>();
            if (id != null) {
                ew.eq("id", id);
            }
            // ew.andNew().eq("est_price", 0).or().isNull("est_price");
            // ew.or().eq("actual_price", 0).or().isNull("actual_price");
            // ew.or().eq("actual_amt", 0).or().isNull("actual_amt");
            //如果存在无价格的数据重新获取合同及报价单信息，绑定价格数据
            List<FeePayable> feePayables = selectListNoTenant(ew);
            if (!CollectionUtils.isEmpty(feePayables)) {
                feePayables.forEach(feePayable -> {
                    createFeePayable(feePayable, true, false);
                });
                updateBatchById(feePayables);
            } else {
                throw new BaseException("无匹配空价格数据");
            }
        } catch (BaseException e) {
            LOGGER.error("FeePayableServiceImpl.updateFeePayablePrice ERROR: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("FeePayableServiceImpl.updateFeePayablePrice ERROR: {}", e.getMessage());
            throw new BaseException("更新应付账单价格失败");
        }
    }

    /**
     * 定时更新应付账款
     */
    @Override
    public void scheduledUpdateFeePayablePrice() {
        try {
            /*
             * 获取价格为0或为空值的数据
             */
            EntityWrapper<FeePayable> ew = new EntityWrapper<>();
            ew.eq("source_sys", 0);
            ew.notLike("fleet_name", "人送");
            Set<Long> fleetIdSet = this.getContractFleetId();
            if (!CollectionUtils.isEmpty(fleetIdSet)) {
                ew.in("fleet_id", fleetIdSet);
            }
            // ew.andNew().eq("est_price", 0);
            // ew.or().eq("actual_price", 0);
            ew.andNew().eq("actual_price", 0);
            ew.or().eq("actual_amt", 0);
            //如果存在无价格的数据重新获取合同及报价单信息，绑定价格数据
            int total = 0;
            int page = 1;
            while (true) {
                Page<FeePayable> objectPage = new Page<>(page, 50);
                List<FeePayable> feePayableList = baseMapper.selectPageNoTenant(objectPage, ew);
                LOGGER.info("\n------------------------SurplusSize: {}------------------------", objectPage.getTotal());

                if (CollectionUtils.isEmpty(feePayableList) || total == objectPage.getTotal()) {
                    break;
                } else {
                    if (!CollectionUtils.isEmpty(feePayableList)) {
                        feePayableList.forEach(feePayable -> {
                            createFeePayable(feePayable, false, false);
                        });
                        updateBatchById(feePayableList);
                    }
                    total = objectPage.getSize();
                }
                page++;
            }
        } catch (BaseException e) {
            LOGGER.error("FeePayableServiceImpl.scheduledUpdateFeePayablePrice error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("FeePayableServiceImpl.scheduledUpdateFeePayablePrice error: {}", e.getMessage());
            throw new BaseException("更新应付账单价格失败");
        }
    }

    private Set<Long> getContractFleetId() {
        Set<Long> fleetIdSet = new HashSet<>();
        Map<String, Object> contractCondition = new HashMap<>();
        contractCondition.put("secondPartyType", "1");
        contractCondition.put("contState", "2");
        contractCondition.put("contractType", "1");
        List<Contract> contractList = contractService.selectContractListNoTenant(contractCondition);
        if (!CollectionUtils.isEmpty(contractList)) {
            contractList.forEach(contract -> {
                String fleetIds = contract.getFleetIds();
                if (fleetIds.contains(",")) {
                    String[] objStrArray = fleetIds.split(",");
                    for (String s : objStrArray) {
                        fleetIdSet.add(Long.valueOf(s));
                    }
                } else {
                    fleetIdSet.add(Long.valueOf(fleetIds));
                }
            });
        }
        Set<Long> sdBaseDataFleetIdSet = sdBaseComputerService.getSdBaseDataFleetIdSet();
        if (!CollectionUtils.isEmpty(sdBaseDataFleetIdSet)) {
            fleetIdSet.addAll(sdBaseDataFleetIdSet);
        }
        return fleetIdSet;
    }

    /**
     * 新增应付账单
     *
     * @param feePayable
     * @return
     */
    @Override
    public FeePayable insertOneFeePayable(FeePayable feePayable) {
        try {

            if (feePayable == null) {
                return null;
            }
            if (feePayable.getStatus() == null) {
                feePayable.setStatus(0);
            }
            feePayable.setGmtCreate(new Date());
            this.insert(feePayable);
        } catch (BaseException e) {
            LOGGER.error("FeePayableServiceImpl.insertOneFeePayable ERROR: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("FeePayableServiceImpl.insertOneFeePayable ERROR: {}", e.getMessage());
            throw new BaseException("应付账款新增失败");
        }
        return feePayable;
    }

    @Override
    public List<FeePayable> insertBatchFeePayable(List<FeePayable> feePayables) {
        try {
            if (!CollectionUtils.isEmpty(feePayables)) {
                feePayables.forEach(feePayable -> {
                    if (feePayable.getStatus() == null) {
                        feePayable.setStatus(0);
                    }
                    feePayable.setGmtCreate(new Date());
                });
            }

            this.insertBatch(feePayables);
        } catch (BaseException e) {
            LOGGER.error("FeePayableServiceImpl.insertBatchFeePayable ERROR: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("FeePayableServiceImpl.insertBatchFeePayable ERROR: {}", e.getMessage());
            throw new BaseException("应付账款新增失败");
        }
        return feePayables;
    }

    /**
     * 给应付账单绑定匹配合同信息
     *
     * @param feePayable
     */
    private Contract bindContractSource(FeePayable feePayable) {
        //获取合同
        Contract contract = getMatchContract(feePayable);
        //绑定合同数据
        if (Objects.isNull(contract)) {
            return null;
        }
        //获取报价单
        // List<QuoteDtl> quoteDtls = getMatchQuoteDeatilByContract(contract.getId(), feePayable.getStaPriceId());

//		if (!Strings.isNullOrEmpty(transTypeName)) {
//			condition.put("transTypeName", transTypeName);
//		}
//		String carService = amgCstService.getCarServiceByVehicelName(feePayable.getVehicleTypeCode(), feePayable.getTransTypeName(), feePayable.getCiamsId());
//		if (StringUtils.isEmpty(carService)) {
//			condition.put("vehicleTypeName", feePayable.getVehicleTypeCode());         //车型名称   <-->   车系名称
//		} else {
//			condition.put("vehicleTypeName", carService);         //车型名称   <-->   车系名称
//		}
//
//		if (!Strings.isNullOrEmpty(feePayable.getCiamsId())) {
//			condition.put("client", feePayable.getCiamsId());       //所属客户<-->分供方名称
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getStartName())) {
//			condition.put("startAddr", feePayable.getStartName());
//		} else {
//			condition.put("startAddr", "");
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getStartCity())) {
//			condition.put("startCity", feePayable.getStartCity());
//		} else {
//			condition.put("startCity", "");
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getStartCounty())) {
//			condition.put("startCounty", feePayable.getStartCounty());
//		} else {
//			condition.put("startCounty", "");
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getEndProvince())) {
//			condition.put("endProvince", feePayable.getEndProvince());                 //目的地省
//		} else {
//			condition.put("endProvince", "");
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getEndCity())) {
//			condition.put("endCity", feePayable.getEndCity());                  //目的地市
//		} else {
//			condition.put("endCity", "");
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getEndCounty())) {
//			condition.put("endCounty", feePayable.getEndCounty());                  //目的地区
//		} else {
//			condition.put("endCounty", "");
//		}
//		if (!Strings.isNullOrEmpty(feePayable.getEndName())) {
//			condition.put("endAddr", feePayable.getEndName());                  //目的地区
//		} else {
//			condition.put("endAddr", "");
//		}

        List<Long> quoteIdList = getQuoteIdList(contract.getId());
        if (!CollectionUtils.isEmpty(quoteIdList)) {
            MatchingResult matchingResult = queryContractPriceRule(feePayable, quoteIdList);
            if (Objects.nonNull(matchingResult)) {
                FleetQuotation fleetQuotation = matchingResult.getFleetQuotation();
                if (fleetQuotation != null) {
                    // 绑定合同
                    if (contract.getContractType() != null) {
                        feePayable.setContractType(contract.getContractType().toString());
                    }
                    feePayable.setContractCode(contract.getContCode());

                    feePayable.setRuleName(matchingResult.getRuleName());
                    // 报价单
                    feePayable.setQuoteId(fleetQuotation.getHeadId());
                    feePayable.setEstPrice(fleetQuotation.getStandardPrice());
                    feePayable.setActualPrice(fleetQuotation.getQuotationPrice());
                    // 报价公里数
                    if (fleetQuotation.getQuotationMileage() != null) {
                        feePayable.setKilometre(fleetQuotation.getQuotationMileage());
                    } else {
                        feePayable.setKilometre(BigDecimal.ZERO);
                    }
                    // 总金额
                    feePayable.setActualAmt(feePayable.getActualPrice().multiply(feePayable.getKilometre()));
                }
            }
        }
        //根据报价单获取价格和公里数
//         if (!CollectionUtils.isEmpty(quoteDtls)) {
//             // 绑定合同
//             if (contract.getContractType() != null) {
//                 feePayable.setContractType(contract.getContractType().toString());
//             }
//             feePayable.setContractCode(contract.getContCode());
//             // 报价单
//             feePayable.setQuoteId(quoteDtls.get(0).getHeadId());
//             feePayable.setEstPrice(quoteDtls.get(0).getStandardPrice());
//
//             feePayable.setActualPrice(quoteDtls.get(0).getQuotationPrice());
// //			// 公里数 = 报价公里数
// //			feePayable.setKilometre(quoteDtls.get(0).getQuotationMileage());
//         } else {
//             return null;
//         }
        return contract;
    }

    /**
     * 获取匹配的规则逻辑
     *
     * @param feePayable
     * @param quoteIdList
     * @return
     */
    private MatchingResult queryContractPriceRule(FeePayable feePayable, List<Long> quoteIdList) {
        List<FleetQuotation> matchQuoteDetailRuleList = getMatchQuoteDetailRules(quoteIdList);
        if (!CollectionUtils.isEmpty(matchQuoteDetailRuleList)) {
            FeePayable updateFee = changeFeePayable(feePayable);
            MatchingResultList matchRuleResult = getMatchRuleResult(updateFee, matchQuoteDetailRuleList);
            if (matchRuleResult != null) {
                List<MatchingResult> firstMatchingResultList = matchRuleResult.getFirstMatchingResultList();
                if (!CollectionUtils.isEmpty(firstMatchingResultList)) {
                    return firstMatchingResultList.get(0);
                }
            }
        }
        return null;
    }

    /**
     * 转换账款信息
     *
     * @param feePayable
     * @return
     */
    private FeePayable changeFeePayable(FeePayable feePayable) {
        FeePayable updateFee = new FeePayable();
        BeanUtils.copyProperties(feePayable, updateFee);
        String carServiceByVehicelName = amgCstService.getCarServiceByVehicelName(updateFee.getVehicleTypeCode(),
                updateFee.getTransTypeName(), updateFee.getCiamsId(), updateFee.getOrderDate());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(carServiceByVehicelName)) {
            updateFee.setVehicleTypeCode(carServiceByVehicelName);
        }
        // 比较时间
        Date date = feePayable.getOrderDate() == null ? feePayable.getGmtCreate() : feePayable.getOrderDate();
        if (date != null) {
            DateTime dateTime = new DateTime(date);
            if (RulePriceEnum.FebDateTime.compareTo(dateTime) > 0) {
                // 二月份之前的数据
                List<TransTypeNameContrast> transTypeNameContrastList = transTypeNameContrastService.selectTransTypeNamesByTypeName(feePayable.getTransTypeName());
                if (!CollectionUtils.isEmpty(transTypeNameContrastList)) {
                    updateFee.setTransTypeName(null);
                }
            } else {
                // 判断业务主体
                if (!RulePriceEnum.ciamsList.contains(updateFee.getCiamsId())) {
                    List<TransTypeNameContrast> transTypeNameContrastList = transTypeNameContrastService.selectTransTypeNamesByTypeName(feePayable.getTransTypeName());
                    if (!CollectionUtils.isEmpty(transTypeNameContrastList)) {
                        updateFee.setTransTypeName(null);
                    }
                }
            }
        }
        return updateFee;
    }


    /**
     * 获取匹配的合同
     *
     * @param feePayable
     * @return
     */
    private Contract getMatchContract(FeePayable feePayable) {
        Map<String, Object> contractCondition = new HashMap<>();
        Date orderDate = feePayable.getOrderDate() == null ? new Date() : feePayable.getOrderDate();
        contractCondition.put("termOfValidity", ToolCommonUtils.getDateToStrFormat(orderDate));
        // contractCondition.put("termOfValidity", feePayable.getOrderDate() == null ? new Date() : feePayable.getOrderDate());
        contractCondition.put("fleetIds", feePayable.getFleetId());
        contractCondition.put("secondPartyType", "1");
        contractCondition.put("contState", "2");
        contractCondition.put("contractType", "1");
        List<Contract> contracts = contractService.selectContractListNoTenant(contractCondition);
        //绑定合同数据
        if (!CollectionUtils.isEmpty(contracts)) {
            return contracts.get(0);
        }
        return null;
    }

    /**
     * 获取报价单id集合
     *
     * @param contractId
     * @return
     */
    private List<Long> getQuoteIdList(Long contractId) {
        Map<String, Object> quoteHeadercondition = new HashMap<>();
        quoteHeadercondition.put("contractId", contractId);
        quoteHeadercondition.put("state", 2);
        List<Quote> quotes = quoteService.selectQuoteListNoTenant(quoteHeadercondition);
        List<Long> quoteIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(quotes)) {
            quotes.forEach(quote -> quoteIds.add(quote.getId()));
            return quoteIds;
        }
        return null;
    }

    /**
     * 获取匹配的报价单明细
     *
     * @param contractId
     * @param staPriceId
     * @return
     */
    private List<QuoteDtl> getMatchQuoteDeatilByContract(Long contractId, Long staPriceId) {
        List<Long> quoteIds = getQuoteIdList(contractId);
        if (!CollectionUtils.isEmpty(quoteIds)) {
            Map<String, Object> condition = new HashMap<>();
            condition.put("headIds", quoteIds);
            condition.put("staPriceId", staPriceId);
            return quoteDtlService.selectQuoteDtlListNoTenant(condition);
        }
        return null;
    }

    /**
     * 获取报价单规则明细
     *
     * @param quoteIdList
     * @return
     */
    private List<FleetQuotation> getMatchQuoteDetailRules(List<Long> quoteIdList) {
        Map<String, Object> quoteCondition = Maps.newHashMap();
        quoteCondition.put("headIds", quoteIdList);
        return quoteDtlService.selectFleetQuotation(quoteCondition);
    }

    /**
     * 匹配规则数据
     *
     * @param feePayable
     * @param fleetQuotationList
     * @return
     */
    private MatchingResultList getMatchRuleResult(FeePayable feePayable, List<FleetQuotation> fleetQuotationList) {
        KieSession kieSession = KieUtil.getKieContainer().newKieSession();
        for (FleetQuotation fleetQuotation : fleetQuotationList) {
            kieSession.insert(fleetQuotation);
        }
        kieSession.insert(feePayable);
        MatchingResultList resultList = new MatchingResultList();
        kieSession.setGlobal("resultList", resultList);
        int ruleFiredCount = kieSession.fireAllRules();
        LOGGER.info("触发了规则共: {}", ruleFiredCount);
        FactHandle factHandle = kieSession.getFactHandle(feePayable);
        if (factHandle != null) {
            kieSession.delete(factHandle);
        }
        kieSession.dispose();
        return resultList;
    }

    /**
     * 生成应付账款
     *
     * @param pricePurchase
     * @param token
     */
    @Override
    public void insertFeePayable(PricePurchase pricePurchase, String token) {
        try {
            FeePayable feePayable = new FeePayable();
            OrderItemDTO orderItemDTOList = null;
            OrderDTO orderDTO;
            CostMid costMid;
            FeeType feeType;
            LspBasicDTO lspBasicDTO;
            Long waybillDetailId = pricePurchase.getShipOrderItemId();
            PriceDeductRate priceDeductRate = null;
            if (!Objects.isNull(pricePurchase)) {
                // 在lisa_price_purchase表中获取OTM运单号明细，租户id，预估金额,起运地，目的地，
                // 分供方ID，分供方名称，公里数,OTM运单号,车队id，车队名称，司机名称，司机id,结算金额( 总金额 )，
                feePayable.setWaybillDtlId(String.valueOf(pricePurchase.getShipOrderItemId()));
                feePayable.setEstAmt(pricePurchase.getExtPurchasePrice());
                feePayable.setStartAddr(pricePurchase.getDepartAdressName());
//                feePayable.setEndAddr(pricePurchase.getDestAdderssName());
                feePayable.setPayeeId(pricePurchase.getLspId());
                feePayable.setPayeeName(pricePurchase.getLspName());
                feePayable.setKilometre(pricePurchase.getMileage());
                feePayable.setWaybillId(pricePurchase.getShipTaskCode());
                feePayable.setFleetId(pricePurchase.getFleetId());
                feePayable.setFleetName(pricePurchase.getFleetName());
                feePayable.setDriverId(pricePurchase.getDriverId());
                feePayable.setDriverName(pricePurchase.getDriverName());
                feePayable.setTenantId(pricePurchase.getTenantId());
                // 车架号
                feePayable.setVin(pricePurchase.getItemUid());
                // 指令编号
                feePayable.setOrderCode(pricePurchase.getShipmentCode());
                // 承运车牌
                feePayable.setVehicleTypeName(pricePurchase.getCarrierPlate());

                // 设置价格
                priceDeductRate = setPrice(feePayable, pricePurchase);
                //feePayable.setActualAmt(getActualAmt(pricePurchase));

//                if (Objects.nonNull(pricePurchase.getTenantId())) {
//                    new AccountBindUtil<FeePayable>().bindCreatorAndTenantId(feePayable,false);
//                }else{
//                    new AccountBindUtil<FeePayable>().bindCreatorAndTenantId(feePayable,true);
//                }

                // 在OMS.lisa_order_item表中查找数量, 车架号, 当前状态(订单状态), 订单号明细ID,车型名称
                if (waybillDetailId != null) {
                    RestfulResponse<ShipOrderItemVO> shipOrderItemById = tmsUtil.getShipOrderItemById(waybillDetailId, token);
                    if (shipOrderItemById != null && shipOrderItemById.getData() != null) {
                        feePayable.setWaybillDtlId(shipOrderItemById.getData().getItemSourceKey());
                        orderItemDTOList = omsUtil.getOrderItemByItemSourceKey(feePayable.getWaybillDtlId());
                    }

                    if (!Objects.isNull(orderItemDTOList)) {
                        // 2018-09-28 linbao 应付账款的运单明细标识
                        feePayable.setNum(orderItemDTOList.getAmount());
                        feePayable.setOrderDtlId(orderItemDTOList.getId());
                        //feePayable.setVin(orderItemDTOList.getIssueItemId());
                        //feePayable.setLoadStatus(orderItemDto.getCurrentStatus());
                        //feePayable.setVehicleTypeName(orderItemDTOList.getMaterial());

                        //通过租户id在lisa_lsp_info表中查找付款方id，付款方名称
                        if (orderItemDTOList.getTenantId() != null) {
                            lspBasicDTO = lspUtil.getLspInfoByTenantId(orderItemDTOList.getTenantId(), token);
                            if (Objects.nonNull(lspBasicDTO)) {
                                feePayable.setPayerId(lspBasicDTO.getId());
                                feePayable.setPayerName(lspBasicDTO.getName());
                            }
                        }
                        //在OMS.lisa_order表中查找订单编号, 下单时间
                        //if (orderItemDTOList.getOrderId() != null) {
                        //    orderDTO = omsUtil.getOrderById(orderItemDTOList.getOrderId(), token);
                        //    if (!Objects.isNull(orderDTO)) {
                        //        feePayable.setOrderCode(orderDTO.getCode());
                        //        feePayable.setOrderDate(orderDTO.getGmtIssue());
                        //    }
                        //}
                    }

                    //在lisa_cost_mid表中查找合同编码, 合同类型, 费用名称, 单价
                    if (feePayable.getWaybillDtlId() != null) {
                        costMid = costMidService.queryCostMidByBillId(feePayable.getWaybillDtlId());
                    } else {
                        costMid = costMidService.queryCostMidByBillId(waybillDetailId.toString());
                    }
                    if (!Objects.isNull(costMid)) {
                        feePayable.setContractCode(costMid.getCode());
                        feePayable.setContractType(costMid.getContractType());
                        feePayable.setTypeName(costMid.getItemName());


                        //根据费用名称在lisa_fee_type表中查找费用类型ID
                        if (!StringUtils.isEmpty(costMid.getItemName())) {
                            feeType = feeTypeService.queryCostMidByBillId(costMid.getItemName());
                            if (!Objects.isNull(feeType)) {
                                feePayable.setTypeId(feeType.getId());
                            }
                        }
                    }

                } else {
                    throw new BaseException("运单号明细id不能为空");
                }
            }
            // 格式化价格
            formSumMoney(feePayable);
            this.insert(feePayable);

            //生成预付账单
            if (priceDeductRate != null && (priceDeductRate.getOilPrepayRate() != null || priceDeductRate.getCashPrepayRate() != null)) {
                // prepayBillService.insertPrepayBill(feePayable, null);
                prepayBillService.createPrepayBillByContract(feePayable, null);
            }
        } catch (BaseException e) {
            LOGGER.error("feePayableServiceImpl.insertFeePayable: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("feePayableServiceImpl.insertFeePayable: {}", e.getMessage());
            throw new BaseException("生成应付账款错误");
        }
    }

    /**
     * 格式化价格 - 保留两位小数
     *
     * @param feePayable
     */
    private void formSumMoney(FeePayable feePayable) {
        if (feePayable.getActualAmt() != null) {
            feePayable.setActualAmt(feePayable.getActualAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            feePayable.setActualAmt(BigDecimal.ZERO);
        }
        if (feePayable.getEstAmt() != null) {
            feePayable.setEstAmt(feePayable.getEstAmt().setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            feePayable.setEstAmt(BigDecimal.ZERO);
        }
        if (feePayable.getActualPrice() != null) {
            feePayable.setActualPrice(feePayable.getActualPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            feePayable.setActualPrice(BigDecimal.ZERO);
        }
        if (feePayable.getEstPrice() != null) {
            feePayable.setEstPrice(feePayable.getEstPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            feePayable.setEstPrice(BigDecimal.ZERO);
        }
        if (feePayable.getKilometre() != null) {
            feePayable.setKilometre(feePayable.getKilometre().setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            feePayable.setKilometre(BigDecimal.ZERO);
        }
    }

    /**
     * 设置价格
     *
     * @param feePayable
     * @param pricePurchase
     */
    private PriceDeductRate setPrice(FeePayable feePayable, PricePurchase pricePurchase) {
        // 计算单价
        PriceDeductRate priceDeductRate = priceDeductRateService.returnPriceDeductRateByFleetId(feePayable.getFleetId());
        if (priceDeductRate != null) {
            //中联标准：支付暂估价*系数
            //一口价：支付实际价格
            if (priceDeductRate.getPayWay() != null) {
                if (priceDeductRate.getPayWay() == 0) {
                    // 标准价
                    if (priceDeductRate.getRate() != null) {
                        BigDecimal multiplySum = pricePurchase.getExtPurchasePrice().multiply(priceDeductRate.getRate());
                        if (priceDeductRate.getPayRate() != null) {
                            feePayable.setActualPrice(multiplySum.multiply(priceDeductRate.getPayRate()));
                        }
                    } else {
                        feePayable.setActualPrice(pricePurchase.getExtPurchasePrice());
                    }
                } else if (priceDeductRate.getPayWay() == 1) {
                    // 一口价
                    feePayable.setActualPrice(pricePurchase.getActPurchasePrice());
                }

            }
        } else {
            feePayable.setActualPrice(pricePurchase.getActPurchasePrice());
        }
        // 计算价格
        if (feePayable.getKilometre() != null) {
            feePayable.setActualAmt(feePayable.getActualPrice().multiply(feePayable.getKilometre()));
        } else {
            feePayable.setActualAmt(feePayable.getActualPrice());
        }

        return priceDeductRate;
    }

    /**
     * 获取应付账款的结算总金额
     *
     * @param pricePurchase
     */
    @Override
    public BigDecimal getActualAmt(PricePurchase pricePurchase) {
        BigDecimal deductRate = null;
        BigDecimal actualAmt = null;
        if (Objects.nonNull(pricePurchase)) {
            PriceDeductRate priceDeductRate = priceDeductRateService.returnPriceDeductRate(pricePurchase.getLspId(), pricePurchase.getFleetId());
            if (Objects.nonNull(priceDeductRate) && Objects.nonNull(priceDeductRate.getRate())) {
                deductRate = priceDeductRate.getRate().setScale(2, BigDecimal.ROUND_HALF_UP);
            } else {
                deductRate = new BigDecimal(1).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            if (Objects.isNull(pricePurchase.getExtPurchasePrice())) {
                pricePurchase.setExtPurchasePrice(new BigDecimal(0));
            }
            BigDecimal extPurchasePrice = pricePurchase.getExtPurchasePrice().multiply(deductRate).setScale(2, BigDecimal.ROUND_HALF_UP);
            if (priceDeductRate.getPayWay() == 1) {
                actualAmt = pricePurchase.getActPurchasePrice();
            } else {
                actualAmt = extPurchasePrice.multiply(priceDeductRate.getPayRate());
            }
        } else {
            LOGGER.error("传入参数不能为空");
        }

        return actualAmt;
    }

    @Override
    public List<FeePayable> getFeePayableByWaybillDtlId(String waybillDtlId, List<Long> ids) {
        if (ObjectUtils.isEmpty(waybillDtlId) || ids.isEmpty()) {
            return null;
        }
        EntityWrapper ew = new EntityWrapper<>();
        ew.in("id", ids);
        ew.eq("waybill_dtl_id", waybillDtlId);
        return this.selectList(ew);
    }

    /**
     * 根据应付账款ID得到账单
     *
     * @param ids
     * @return
     */
    @Override
    public List<Bill> getBillByFeePayableID(List<Long> ids) {
        return billDetailService.getBillByfeeId(ids);
    }

    /**
     * 根据主键，修改应付账款
     *
     * @param feePayable
     */
    @Override
    public void updateFeePayable(FeePayable feePayable) {
        this.updateById(feePayable);
    }

    /**
     * 根据账单ID，得到多个应付账款聚合金额
     *
     * @param billId
     * @return
     */
    @Override
    public BigDecimal getFeePayableDeductTotalByBillid(Long billId) {
        return baseMapper.getFeePayableDeductTotalByBillid(billId);
    }

    /**
     * 根据车队id获取对应合同车队明细
     *
     * @param feePayableId
     * @return
     */
    @Override
    public List<ContractFinalpay> getContractFinalpayList(Long feePayableId) {
        FeePayable feePayable = this.selectById(feePayableId);
        String contractCode = feePayable.getContractCode();
        return contractFinalpayService.selectContractFinalpayListByHeadCode(contractCode);
    }

    /**
     * 根据条件获取指定列的总和
     *
     * @param columnType
     * @param condition
     * @return
     */
    @Override
    public Object getColumnSum(String columnType, Map<String, Object> condition) {
        if (!StringUtils.isEmpty(columnType)) {
            String columnVal = "";
            EntityWrapper<FeePayable> entityWrapper = new EntityWrapper();
            if ("oilBaPay".equals(columnType)) {
                entityWrapper.setSqlSelect("SUM(oil_ba_pay)");
            } else if ("cashBaPay".equals(columnType)) {
                entityWrapper.setSqlSelect("SUM(cash_ba_pay)");
            } else if ("insurancePrice".equals(columnType)) {
                entityWrapper.setSqlSelect("SUM(else_price)");
            }
            condition.forEach((s, o) -> {
                if ("billHeadId".equals(s)) {
                    List<Long> feeIds = new ArrayList<>();
                    List<BillDetail> billDetailList = billDetailService.getBillDetailList(new Long(String.valueOf(o)));
                    if (!CollectionUtils.isEmpty(billDetailList)) {
                        billDetailList.forEach(billDetail -> feeIds.add(billDetail.getFeeId()));
                    }
                    entityWrapper.in("id", feeIds);
                }
            });
            Object o = selectObj(entityWrapper);
            return (o == null ? "0" : o);
        }
        return null;
    }
}
